home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 12 - 1996 / 12.12 Dec 96 / Flat File Databases / Invoice Example ƒ / GUI ƒ / DialogCode.c < prev   
Encoding:
Text File  |  1996-03-02  |  15.0 KB  |  529 lines  |  [TEXT/CWIE]

  1. //this is code from DTS; we use some of it.  I left the rest in 
  2. //a) because it wasn't hurting anyone and
  3. //b) it might be of interest to others.
  4.  
  5.  
  6. #include "SampleHeader.h"
  7. #include "SampleGlobals.h"
  8. #include "InvoiceGlobals.h"
  9. #include "Actions.h"
  10. #include "NOC.h"
  11. #define kArrow 1
  12. #define kIBeam    2
  13.  
  14.  
  15.  
  16. /*-------------------------------------------------------------------------------------*/
  17. /*
  18.     GetCtlHandle - Just a handy way to get a control's handle given only the item
  19.     number and the dialog.
  20. */
  21. /*static*/ ControlHandle GetCtlHandle(DialogPtr theDialog, short theItem)
  22. {
  23.     Handle     theControl;
  24.     short    aType;
  25.     Rect    aRect;
  26.     
  27.     GetDItem(theDialog, theItem, &aType, &theControl, &aRect);
  28.     if (theControl == nil )
  29.         DebugStr((StringPtr)"\pGetDItem in GetCtlHandle failed");
  30.  
  31.     return (ControlHandle)theControl;
  32. }
  33.  
  34.  
  35. /*-------------------------------------------------------------------------------------*/
  36. /*
  37.     SetDialogControlHilite - makes the control active and sets the control value to
  38.     whatever you want.
  39.     
  40. */
  41. static void SetDialogControlHilite(DialogPtr theDialog, short whichItem, Boolean isHilited)
  42. {
  43.     ControlHandle    theControl;
  44.  
  45.     theControl = GetCtlHandle(theDialog, whichItem);
  46.     if (theControl == nil )
  47.     {
  48.         DebugStr((StringPtr)"\pGetCtlHandle in SetDialogControlHilite failed");
  49.         return;
  50.     }
  51.     HiliteControl(theControl, 0);
  52.     SetCtlValue(theControl, isHilited);
  53. }
  54.  
  55.  
  56. /*-------------------------------------------------------------------------------------*/
  57. /*
  58.     DisableDialogControl - disables a dialog control by deactivating it (to turn off 
  59.     hit detection) and sets its value to 0.
  60. */
  61. static void DisableDialogControl(DialogPtr theDialog, short whichItem)
  62. {
  63.     ControlHandle    theControl;
  64.  
  65.     theControl = GetCtlHandle(theDialog, whichItem);
  66.     if ( theControl != nil )
  67.     {
  68.         SetCtlValue(theControl, 0);
  69.         HiliteControl(theControl, 255);
  70.     }
  71.     else
  72.         DebugStr((StringPtr)"\pthe handle was nil");
  73. }
  74.  
  75.  
  76. /*-------------------------------------------------------------------------------------*/
  77. /*
  78.     DoDialogEvent - After checking that EventFilter's result is TRUE, this calls 
  79.     DialogSelect to check if any controls were hit, and if so this acts accordingly.
  80. */
  81. void DoDialogEvent(EventRecord *theEvent)
  82. {
  83.     DialogPtr    theDialog = (DialogPtr)FrontWindow();
  84.     short        theItem;
  85.     GrafPtr        origPort;
  86.     char        theKey;
  87.  
  88.     GetPort(&origPort);
  89.     SetPort(theDialog);
  90.     
  91.     if ((theEvent->what==keyDown)||(theEvent->what==autoKey)) {
  92.         theKey = theEvent->message & charCodeMask;
  93.  
  94.                 if ( (theEvent->modifiers & cmdKey) != 0 ) 
  95.                 {    
  96.                     long menuResult;
  97.                     menuResult = MenuKey(theKey);
  98.             
  99.                     if ( (menuResult  >> 16) != 0 )
  100.                     {
  101.                         Boolean editOpPerformed = MenuCommand(menuResult);
  102.                     }
  103.                 }        
  104.     }
  105.     if (DialogSelect(theEvent, &theDialog, &theItem)== true) {
  106.         if (theDialog == gCustomerDialog) {
  107.             HandleCustomerAction(theEvent,&theItem);
  108.             return;
  109.             }
  110.         if (theDialog == gPartDialog) {
  111.             HandlePartAction(theEvent,&theItem);
  112.             return;
  113.             }
  114.         if (theDialog ==gInvoiceDialog) {
  115.             HandleInvoiceAction(theEvent,&theItem);
  116.             return;
  117.             }
  118.     }
  119.     else
  120.         DoDialogNullEvent(theEvent);
  121.  
  122. }
  123.  
  124.  
  125. /*-------------------------------------------------------------------------------------*/
  126. /*
  127.     FakeButtonHilite - The recommended way to fake a button being hit.  If the user 
  128.     hits escape to quit a dialog, this is called to give visual feedback that the
  129.     dialog is cancelled.
  130. */
  131. static void FakeButtonHilite(DialogPtr theDialog, short buttonItemNum)
  132. {
  133.     long throwAway;
  134.  
  135.     ControlHandle buttonHandle = GetCtlHandle(theDialog, buttonItemNum);
  136.     if ( buttonHandle != nil )
  137.     {
  138.         HiliteControl(buttonHandle, true);
  139.         Delay(8, &throwAway);
  140.         HiliteControl(buttonHandle, false);
  141.     }
  142.  
  143. }
  144.  
  145.  
  146. /*-------------------------------------------------------------------------------------*/
  147. /*
  148.     InvalThisItemRect - A handly way to invalidate a dialog item.  This is used to 
  149.     invalidate the edit text field of the dialog in response to the check box being 
  150.     hit.
  151. */
  152. /*static*/ void InvalThisItemRect(DialogPtr theDialog, short theEditItem)
  153. {
  154.     Handle            editTextItem;
  155.     short            aType;
  156.     Rect            editTextRect;
  157.     GrafPtr            oldPort;
  158.  
  159.     GetPort(&oldPort);
  160.     SetPort(theDialog);
  161.     
  162.     GetDItem(theDialog, theEditItem, &aType, &editTextItem, &editTextRect);
  163.     InsetRect(&editTextRect, -5, -5);
  164.     InvalRect(&editTextRect);
  165.     
  166.     SetPort(oldPort);
  167. }
  168.  
  169.  
  170. /*-------------------------------------------------------------------------------------*/
  171. /*
  172.     CreateModelessDialog - Creates the modeless dialog (from a DLOG resource) and sets
  173.     up the initial state of the controls and user items.  Note that it also allocates
  174.     two globals that will always point to the user item proc routines.  This is needed
  175.     only once and can be called by all sebsequent calls to CreateModelessDialog, because
  176.     the routines won't change.  In the 68k world, these routines are redefined to just 
  177.     be plain old proc pointers, and on PowerPC bulids they use real UPPs.
  178. */
  179. void CreateModelessDialog(short DialogID, DialogPtr *theNewDialog)
  180. {
  181.     /*short     tempType;
  182.     Handle    tempHandle;
  183.     Rect    tempRect;
  184.     
  185.     static UserItemUPP    procForDimUserItem = nil;
  186.     static UserItemUPP    procForBorderUserItem = nil; */
  187.     *theNewDialog = NULL;
  188.     *theNewDialog = GetNewDialog(DialogID, nil, (WindowPtr)-1);
  189.     if (*theNewDialog !=NULL) {
  190.         ShowWindow(*theNewDialog);
  191.     }
  192.         return;
  193.  
  194.     }
  195.  
  196. /*-------------------------------------------------------------------------------------*/
  197. /*
  198.     DimEditLine - If the dialog is not frontmost and the edit check box is false, this
  199.     will draw the edit text dialog item in 'disabled' mode.
  200. */
  201. static pascal void DimEditLine(WindowPtr theDialog, short theItem)
  202. {
  203.     ControlHandle theControl;
  204.     
  205.     theControl = GetCtlHandle(theDialog, kEditCheckItem);
  206.     /* only do it if the checkbox is false */
  207.     if ( (GetCtlValue(theControl) == false) || (theDialog != FrontWindow()) )
  208.     {
  209.         PenState     thePen;
  210.         short         itemType;
  211.         Handle         itemHandle;
  212.         Rect         dimRect;
  213.  
  214.         /* Save and restore the pen state so we don't mess things up for other */
  215.         /* drawing routines */
  216.         GetPenState(&thePen);
  217.         GetDItem(theDialog, theItem, &itemType, &itemHandle, &dimRect);
  218.         PenMode(notPatBic);
  219.         PenPat(&qd.gray);
  220.         PaintRect(&dimRect);
  221.         SetPenState(&thePen);
  222.         
  223.     }
  224. }
  225.  
  226.  
  227. /*-------------------------------------------------------------------------------------*/
  228. /*
  229.     HiliteAllControls - This is used in response to activate events for the dialog.  If
  230.     an activate event is sent, hilite all controls to be active, and if its a deactivate
  231.     event, unhilite all controls.
  232. */
  233. static void HiliteAllControls(DialogPtr theDialog, short hiliteCode)
  234. {
  235.     ControlHandle theControl;
  236.  
  237.     InvalThisItemRect(theDialog, kEditTextField);
  238.  
  239.     theControl = GetCtlHandle(theDialog, kEditCheckItem);
  240.     if ( theControl != nil )
  241.         HiliteControl(theControl, hiliteCode);
  242.  
  243.     theControl = GetCtlHandle(theDialog, kCancelButton);
  244.     if ( theControl != nil )
  245.         HiliteControl(theControl, hiliteCode);
  246.  
  247.  
  248.     theControl = GetCtlHandle(theDialog, kOkayButton);
  249.     if ( theControl != nil )
  250.         HiliteControl(theControl, hiliteCode);
  251.  
  252. }
  253.  
  254.  
  255. /*-------------------------------------------------------------------------------------*/
  256. /*
  257.     DrawButtonBorder - Standard way to draw a border around the default button.
  258. */
  259. static pascal void DrawButtonBorder(WindowPtr theDialog, short theItem)
  260. {
  261. #pragma unused (theItem)
  262.     Handle            theControl;
  263.     short            aType;
  264.     Rect            aRect;
  265.  
  266.     GetDItem((DialogPtr)theDialog, kOkayButton, &aType, &theControl, &aRect);
  267.     
  268.     PenSize(3,3);
  269.     InsetRect(&aRect, -4, -4);
  270.     FrameRoundRect(&aRect, 16,16);
  271. }
  272.  
  273.  
  274. /*-------------------------------------------------------------------------------------*/
  275. /*
  276.     DoCut - Zero out the scrap and cut the current selection from the current edit text
  277.     field.  Done in response to the Cut menu command (either by key or mouse).
  278.  
  279.     Note that we don't have to worry about putting the TEScrap->DeskScrap stuff
  280.     in response to suspend/resume events, because the desk scrap is always
  281.     kept up-to-date.
  282. */
  283. void DoCut(DialogPtr theDialog)
  284. {
  285.     HiliteMenu(kEditMenuID);
  286.     (void)ZeroScrap();
  287.     DlgCut(theDialog);
  288.     if ( TEToScrap() != noErr )
  289.         DebugStr((StringPtr)"\pProblem going from TE->desk scrap");
  290. }
  291.  
  292.  
  293. /*-------------------------------------------------------------------------------------*/
  294. /*
  295.     DoCut - Zero out the scrap and copy the current selection from the current edit text
  296.     field.  Done in response to the Copy menu command (either by key or mouse).
  297.  
  298.     Note that we don't have to worry about putting the TEScrap->DeskScrap stuff
  299.     in response to suspend/resume events, because the desk scrap is always
  300.     kept up-to-date.
  301. */
  302. void DoCopy(DialogPtr theDialog)
  303. {
  304.     HiliteMenu(kEditMenuID);
  305.     (void)ZeroScrap();
  306.     DlgCopy(theDialog);
  307.     if ( TEToScrap() != noErr )
  308.         DebugStr((StringPtr)"\pProblem going from TE->desk scrap");
  309. }
  310.  
  311.  
  312. /*-------------------------------------------------------------------------------------*/
  313. /*
  314.     DoPaste - Paste the current selection from the current edit text
  315.     field.  Done in response to the Paste menu command (either by key or mouse).
  316.  
  317.     Note that we don't have to worry about putting the TEScrap->DeskScrap stuff
  318.     in response to suspend/resume events, because the desk scrap is always
  319.     kept up-to-date.
  320. */
  321. void DoPaste(DialogPtr theDialog)
  322. {
  323.     if ( TEFromScrap() != noErr )
  324.         DebugStr((StringPtr)"\pProblem going from desk scrap->TE");
  325.     HiliteMenu(kEditMenuID);
  326.     DlgPaste(theDialog);
  327.  
  328. }
  329.  
  330.  
  331. /*-------------------------------------------------------------------------------------*/
  332. /*
  333.     DoClear - Cut the current selection from the current edit text field, but don't
  334.     add it to the scrap.  Done in response to the Cut menu command (either by key 
  335.     or mouse).
  336. */
  337. void DoClear(DialogPtr theDialog)
  338. {
  339.     HiliteMenu(kEditMenuID);
  340.     DlgDelete(theDialog);
  341. }
  342.  
  343.  
  344. /*-------------------------------------------------------------------------------------*/
  345. /*
  346.     DoDialogNullEvent - This handles updating the cursor as it flys over an active edit
  347.     text field.  It also calls DialogSelect which is necessary if you have any edit
  348.     text dialog fields, and you want that cursor to blink.
  349. */
  350. void DoDialogNullEvent(EventRecord *theEvent)
  351. {
  352.     WindowPtr    currFrontWindow = FrontWindow();
  353.     short        throwAwayItem;
  354.     GrafPtr        origPort;
  355.     static short    oldCursor = kArrow;
  356.     GetPort(&origPort);
  357.     SetPort(currFrontWindow);
  358.     
  359.     if ( currFrontWindow != nil )
  360.     {
  361.         if ( (((WindowRecord *)currFrontWindow)->windowKind == dialogKind)
  362.             && !gInBackground )
  363.         {
  364.             Point    tempPt;
  365.             Rect    FieldRect;
  366.             static     Rect     oldFieldRect;
  367.             short    throwAwayType;
  368.             Handle    throwAwayHandle;
  369.             short    numItems;
  370.             short    i;
  371.             CursHandle    theCursor=NULL;
  372.             static Boolean    changeIt=FALSE;
  373.             GetMouse(&tempPt);
  374.             i = FindDialogItem(currFrontWindow, tempPt) +1;
  375.                 GetDItem(currFrontWindow, i, &throwAwayType, &throwAwayHandle, &FieldRect);
  376.                 if ((throwAwayType==editText)&&(oldCursor==kArrow)) {
  377.                     theCursor = GetCursor(iBeamCursor);
  378.                     HLock((Handle)theCursor);
  379.                     SetCursor(*theCursor);
  380.                     HUnlock((Handle)theCursor);
  381.                     oldCursor = kIBeam;
  382.                     
  383.                 }
  384.     
  385.             else if((throwAwayType!=editText)&&(oldCursor==kIBeam)){
  386.                 SetCursor(&qd.arrow);
  387.                 oldCursor = kArrow;
  388.                 }        
  389.             }    
  390.             
  391.         }
  392.             DialogSelect(theEvent, &currFrontWindow, &throwAwayItem);
  393.             SetPort(origPort);
  394.     }
  395.  
  396.  
  397.     
  398.  
  399.  
  400.  
  401.  
  402.  
  403. /*-------------------------------------------------------------------------------------*/
  404. /*
  405.     EventFilter - This is the first thing done if a dialog event is received, giving 
  406.     you a chance to perform any special stuff before passing control on to 
  407.     DialogSelect.
  408.     
  409.     If this routine returns true, the event processing will continue, and DialogSelect
  410.     will be called to perform hit detection on the controls.  If false is returned,
  411.     it means the event is already handled and the main event loop will continue.
  412. */
  413. Boolean EventFilter(EventRecord *theEvent, WindowPtr theFrontWindow)
  414. {
  415.     Handle        editFieldHandle;
  416.     short        aType;
  417.     Point        tempPt;
  418.     Rect        editFieldRect;
  419.     char         theKey;
  420.     short         theHiliteCode;
  421.     
  422.     if ( ((WindowRecord *)theFrontWindow)->windowKind == dialogKind )
  423.         GetDItem((DialogPtr)theFrontWindow, kEditTextField, &aType, &editFieldHandle, &editFieldRect);
  424.  
  425.     switch ( theEvent->what )
  426.     {    
  427.         case mouseDown:
  428.         case mouseUp:
  429.                 tempPt = theEvent->where;
  430.                 GlobalToLocal(&tempPt);
  431.  
  432.                 /* Check if the mouseDown was in the editText field         */
  433.                 /* (like for text selection or cursor placement.  If         */
  434.                 /* the checkbox isn't checked, do nothing and return         */
  435.                 /* false so DialogSelect doesn't mess with it.                 */
  436.                 if ( PtInRect(tempPt, &editFieldRect) && 
  437.                     (GetCtlValue(GetCtlHandle((DialogPtr)theFrontWindow, kEditCheckItem)) == false) )
  438.                     return false;
  439.                 break;
  440.  
  441.         case keyDown:
  442.         case autoKey:    
  443.                 theKey = theEvent->message & charCodeMask;
  444.  
  445.                 if ( (theEvent->modifiers & cmdKey) != 0 ) 
  446.                 {    
  447.                     long menuResult;
  448.                     menuResult = MenuKey(theKey);
  449.             
  450.                     if ( (menuResult  >> 16) != 0 )
  451.                     {
  452.                         Boolean editOpPerformed = MenuCommand(menuResult);
  453.                         
  454.                         if ( editOpPerformed == true )
  455.                             /* You may ask yourself, "Why are we exiting when an     */
  456.                             /* edit operation is performed?"  Well, DialogSelect     */
  457.                             /* performs some automatic handling for any editText     */
  458.                             /* items that may be in the Dialog, and since we've     */
  459.                             /* already handled them in MenuCommand() we don't         */
  460.                             /* want  DialogSelect to do anything                     */
  461.                             return false;
  462.                     }
  463.                 }
  464.                 else if ( ((theEvent->message) & charCodeMask) == 0x1B )
  465.                 {
  466.                     /* Was Cancel hit?  We could also check for Return     */
  467.                     /* or Enter being hit, but in this example the edit */
  468.                     /* text field is multi-lined, so I'm quitting on     */
  469.                     /* return.  You get the idea..                         */
  470.                     FakeButtonHilite((DialogPtr)theFrontWindow, kCancelButton);
  471.                     DisposeDialog((DialogPtr)theFrontWindow);
  472.                     return false;
  473.                 }
  474.                 
  475.                 if ( (((DialogPeek)theFrontWindow)->editField + 1 == kEditTextField) 
  476.                     && (GetCtlValue(GetCtlHandle((DialogPtr)theFrontWindow, kEditCheckItem)) == false) )
  477.                     /* Finally, if any non-command keystrokes were         */
  478.                     /* entered and the edit field is disabled, exit.     */
  479.                     return false;
  480.  
  481.                 break;
  482.  
  483.         case activateEvt:                
  484.                 /* This is where we take care of hiliting the        */
  485.                 /* controls according to whether or not the dialog     */
  486.                 /* is frontmost.                                     */
  487.                 theFrontWindow = (WindowPtr)theEvent->message;
  488.                 if ( (theEvent->modifiers & activeFlag) == true )
  489.                     theHiliteCode = 0;
  490.                 else
  491.                     theHiliteCode = 255;
  492.  
  493.                 HiliteAllControls((WindowPtr)theFrontWindow, theHiliteCode);
  494.                 return false;
  495.  
  496.     }
  497.  
  498.     /* If we haven't returned false by now, go ahead    */
  499.     /* and return true so DialogSelect can do its         */
  500.     /* thing, like update the window, deal with an         */
  501.     /* item hit, etc.                                    */
  502.     return true;
  503. }
  504.  
  505. // this function simplifies turning  a control on and off active status in a dialog
  506. // from (ERR)
  507.  
  508. void ToggleControl(DialogPtr theDialog, short theItem, const short whichway){
  509.     GrafPtr oldPort;
  510.     short theItemType;
  511.     Handle item;
  512.     Rect box;
  513.     GetPort(&oldPort);
  514.     SetPort(theDialog);
  515.     GetDialogItem(theDialog,theItem, &theItemType, &item, &box);
  516.     if (whichway ==1)
  517.         HiliteControl((ControlHandle)item,0);
  518.     else
  519.         HiliteControl((ControlHandle)item,255);
  520.     SetDialogItem(theDialog, theItem, theItemType, item, &box);
  521.     InsetRect(&box,-5,-5);
  522.     InvalRect(&box);
  523.     BeginUpdate(theDialog);
  524.     DrawDialog(theDialog);
  525.     EndUpdate(theDialog);
  526.     SetPort(oldPort);
  527. }// function
  528.  
  529.